//#include "StdAfx.h"
//#include "TmsPacket.h"

#include <sys/types.h>
#include <stdint.h>
#include "tms.h"

extern uint8_t lrc(uint8_t lrc, uint8_t *buffer, uint32_t len);


#define STX 0X02
#define ETX 0X03
int PacketFrame(unsigned char * data, int data_len, unsigned char *out_data)
{
	unsigned char tmp[MAX_FREME_LEN];
	if (data_len > MAX_DATA_LEN)
	{
		return -1;
	}
	tmp[0] = STX;
	tmp[2] = (data_len >> 8) & 0xff;
	tmp[1] = data_len & 0xff;
	memcpy(tmp + 3, data, data_len);
	tmp[data_len + 3] = lrc(0, data, data_len);
	tmp[data_len + 4] = ETX;
    memcpy(out_data, tmp, data_len + 5);
	return data_len + 5;
}
/*************************************************************************
* Function: ResolveFrame.
*---------------------------------------------------------------------
* Data Structure:
* 			1B		 2B		   <= 1024B   1B   1B
* Frame:  {<STX> <DataLength> <Data Area><LRC><ETX>}
*---------------------------------------------------------------------	  
* parameter:
* 	sBuf ---    buffer use to store the unresolved-frame
*   sBuflen --- unresolved-frame len
* 	dBuf ---    buffer use to store the resolved-frame
* return:  
*	>= 0 --- the resolved-frame len.
*	<  0 --- resolve a frame fail.
**************************************************************************/
int ResolveFrame(unsigned char * s_buf, int s_buf_len, unsigned char * d_buf)
{
	int pos = 0;
	int step = 0;
	int tmplen = 0;//
	int dataLen = 0;
	int lrc_val = 0;
	unsigned char tmp[MAX_FREME_LEN];
	memset(tmp, 0, MAX_FREME_LEN);
	int buff_len = 0;
	if (s_buf_len > MAX_FREME_LEN)
	{
		return -1;
	}
	while(s_buf_len > pos)
	{					
		switch(step)
		{
		case 0: /* see first FSTX */
			if((s_buf[pos++]) == STX)
			{
				step++;
				tmplen = 0;
				tmp[0] = STX;
				buff_len = 1;
				//PrintfStr(_T("see first FSTX"));
			}
			break;
		case 1: //{<Data Length>}
			tmp[buff_len++] =(s_buf[pos++]);
			tmplen++;
			
			if(tmplen == 2)
			{
				step++;
				tmplen = 0;
				dataLen = (s_buf[pos-1] << 8) + s_buf[pos-2];
                if (dataLen > MAX_DATA_LEN) {
                    return -1;
                }
				//CString str;
				//str.Format(_T("datalen:%d"), dataLen);
				//PrintfStr(str);
			}
			break;
		case 2: //{<Data>}
			if(dataLen != 0)
			{
				tmp[buff_len++] = (s_buf[pos++]);
				tmplen++;
			}
			if(tmplen == dataLen)
			{
				step++;
				tmplen = 0;

				lrc_val = (int)lrc(0 , tmp + 3, dataLen);	

			}
			break;
		case 3://{<LRC>}
			tmp[buff_len++] = (s_buf[pos++]);
			tmplen++;
			if(tmplen == 1)
			{
				step++;
				tmplen = 0;
				int lrcVal = s_buf[pos-1];
				//CString str;
				//str.Format(_T("lrcVal:%x lrc:%x"), lrcVal, lrc);
				//PrintfStr(str);
				if(lrcVal != lrc_val)
				{
					step = 0;
				}
			}
			break;	
		case 4://{<Receive End flag >}
			if((s_buf[pos++]) == ETX)
			{
				memcpy(d_buf, tmp + 3, buff_len - 4);

				return buff_len - 4;
			}
			step = 0;
			break;
		default:
			break;

		}
	}

	return -1;
}

#if 0
UINT32 GetTransCode(unsigned char * s_buf)
{
	UINT32 trans_code = 0;

	trans_code = (s_buf[124] << 24) + (s_buf[125] << 16) + (s_buf[126] << 8) + s_buf[127];

	return trans_code;
}
void TmsPacketTest()
{
	byte input[256];
	byte output[256];
	byte packet_data[256];
	int data_len = 0;
	int out_len = 0;
	int packet_len = 0;
	data_len = hexStringToBytes(_T("78965212345678"), input);
	packet_len = PacketFrame(input, data_len, packet_data);
	ComShowDebug(packet_data, packet_len);
	out_len = ResolveFrame(packet_data, packet_len, output);
	if (out_len > 0)
	{
		ComShowDebug(output, out_len);
	}
}

#endif
